Adding Custom Fields to Search

1) I think that your solution is perfectly acceptable in terms of the “right way” – post meta is intended for searching. Doesn’t seem hacky to me.

2) What you should do is build the meta_query separately:

$meta_query = array();

if( !empty( $_GET['price'] ) ) {
    $meta_query[] = array( 'key' => '_price', 'value' => $_GET['price'] );
}
if( !empty( $_GET['year'] ) ) {
    $meta_query[] = array( 'key' => '_year', 'value' => $_GET['year'] );
}

$search = new WP_Query( array(
    'post_type' => 'carcpt',
    'meta_query' => $meta_query
) );

This way you’re only querying on meta keys that have a supplied, non-empty value.

I would like to point out that modification of query variables is better done in the pre_get_posts action, otherwise, as in this instance two queries will be executed: one for the search of ‘carcpt’, and then the second query for the ‘carcpt’ post type and meta query.