I would start by reorganizing your $args
code to make more sense.
$now = date('d-m-Y H:i:s');
$cat="featured";
$args = $cat_args = array(
'post_type' => 'events',
'posts_per_page' => 4,
'meta_key' => 'start_date',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'start_date',
'value' => date('Ymd', strtotime('now')),
'type' => 'numeric',
'compare' => '>=',
),
array(
'key' => 'end_date',
'value' => date('Ymd', strtotime('now')),
'type' => 'numeric',
'compare' => '>=',
),
),
);
// Set the $cat_args array to the category tax_query
$cat_args['tax_query'] = array(
array(
'taxonomy' => 'events_tag',
'field' => 'slug',
'terms' => $cat,
'operator' => 'IN'
),
);
if ( get_posts( $cat_args ) ) { // See if any category posts exist
$query_args = $cat_args;
} else { // Otherwise, pass original $args
$query_args = $args;
}
// Use the newly set $query_args
$wp_query = new WP_Query($query_args);