String handling by OneHotEncoder
This seems to fail only when you're using categorical_features, which was deprecated at the same time the encoder was extended to strings.  Using the now-recommended ColumnTransformer to specify which columns to encode works with strings (as does applying the encoder to the entire frame, though that's not what you want, with features like bmi).

E.g.,

onehot = OneHotEncoder(...)
cat_cols = [1,4,5]
preproc = ColumnTransformer(transformers=[('onehot', onehot, cat_cols)],
                            remainder='passthrough')
preproc.fit_transform(X)