You could use PCA or KernelPCA in a Pipeline to find out how many components suit your situation best. I am not too familiar with decomposition however, so take this with a grain of salt.

KernelPCA + basic DecisionTree example: the estimator will create 3 folds for each `kpca__n_component` and compare their test results to find out what value performs better. You could also add parameters for your decision tree inside the pipeline using e.g. `dtree__min_samples_split=4`.

    from sklearn.decomposition import KernelPCA
    from sklearn.pipeline import Pipeline
    from sklearn.model_selection import GridSearchCV
    from sklearn.tree import DecisionTreeRegressor
    
    dtree = DecisionTreeRegressor()
    kpca = KernelPCA(kernel='rbf')

    pca_pipe = Pipeline(steps=[('kpca', kpca), ('dtree', dtree)])
    
    estimator = GridSearchCV(pca_pipe, param_grid=dict(
                        kpca__n_components = [4, 8, 12, 16, None]))
    estimator.fit(X, y)
    
    print estimator.best_params_, estimator.best_score_

The above code will print the best $R^2$ score and the corresponding n_components value of the KernelPCA object. This score is computed using DecisionTreeRegressor after transforming the data using KernelPCA. After the PCA transformation you can get the original features back using `kpca.inverse_transform([X_transformed])` so you can traceback what features were used in creating the tree.
 
To truly improve your $R^2$ score I would suggest using an ensemble of trees such as GradientBoost or RandomForest instead of a single one, although this is not always feasible.