AFAIK there’s no way to achieve that within a single WP_Query, so you’ll have to first get a list of term_ids which have a different year than the one in question.
I think with the following you’ll come quite close. (don’t have a env to test right away)
$other_years_terms = get_terms(
'taxonomy' => 'vintage',
'meta_key' => 'year_numeric',
'meta_value' => $the_current_wine_year, // You'll have to figure that out
'meta_compare' => '!=',
'fields' => 'ids'
);
$other_years_posts = get_posts(array(
'post_type' => 'product',
'numberposts' => -1,
'tax_query' => array(
array(
'taxonomy' => 'family',
'field' => 'id',
'terms' => $family->term_id, // Where term_id of Term 1 is "1".
'include_children' => false
),
array(
'taxonomy' => 'size',
'field' => 'id',
'terms' => $size->term_id, // Where term_id of Term 1 is "1".
'include_children' => false
),
array(
'taxonomy' => 'vintage',
'field' => 'term_id',
'terms' => $other_years_terms,
),
)
));