tax_query (if the terms are empty)

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);