wp_query add arguments using array_push if variable met

I would suggest trying not to over-complicate the logic. You have the general thought process correct in your question. Assuming everything above works when you just add the meta_query logic to the query directly and run it, then your code should try to follow that same thought pattern.

You’re accessing the globals – so list those out first. This will also make it so they are easy to reference later on when you need to come back to what you’ve done:

    // Globals.
    global $wp_query, $paged, $post;

Now you are getting the short code attributes, it’s discouraged to use extract here, so I’d recommend just setting that to a variable:

Note: You will need to update the locations where you refer to the variables extracted with reference to your shortcode attributes array. I just named it $sc for this example.

    // Shortcode attributes.
    $sc = shortcode_atts(
        array(
            'pagination' => 'true',
            'query' => '',
            'category' => '',
            'tag_name' => '',
            'custom_field_1' => '',
            'custom_field_2' => '',
            'relation_operator' => '',
            'number_posts' => '',
            'order_by'   => '',
            'order'     => '',
        ),
        $atts
    );

Next, you are wanting to modify your WP_Query arguments if your conditions are met, so put your default query arguments next, $args:

Note: get_query_var accepts a default as the second argument passed, so you can cut out that conditional and cast to an int with the default param set (this is significantly faster than the logic used in the question and produces the same outcome [ie absint internally calling intval compared to casting to int]). I’d probably just stick this in your $args directly instead of set a variable for it.

    // WP_Query arguments
    $args = array(
        'paged'          => ( int ) get_query_var( 'paged', 1 ),
        'post_type'      => array( 'page', ' post' ),
        'post_status'    => array( 'publish' ),
        'category_name'  => $sc['category'],
        'tag'            => $sc['tag_name'],
        'category__in'   => $theCatId,       
        'posts_per_page' => $sc['number_posts'],
        'order'          => $sc['order'],
        'orderby'        => $sc['order_by'],
    );

Now you want to add your conditions and modify the arguments if certain things are met:

Note: You can use if ( ! empty( $custom_field_1 ) ) if you wish. I just find if ( $custom_field_1 ) easier to read/faster to write, but that’s just personal preference.

    // custom_field_1 is populated.
    if ( $sc['custom_field_1'] ) {

        // custom_field_2 is populated.
        if ( $sc['custom_field_2'] ) {
            $args['meta_query'] = array(
                    'relation' => $sc['relation_operator'],
                    array(
                        'key'     => $sc['custom_field_1'],
                        'value'   => '',
                        'compare' => '!=',
                    ),
                    array(
                        'key'     => $sc['custom_field_2'],
                        'value'   => '',
                        'compare' => '!=',
                    ),
                )
            );

        // custom_field_2 is not populated.
        } else {
            $args['meta_query'] = array(
                array(
                    'key'     => $sc['custom_field_1'],
                    'value'   => '',
                    'compare' => '!=',
                ),
            );
        }
    }

Now you’ve modified the arguments as you desired, so create your query:

    // Custom query $my_query.
    $my_query = new WP_Query( $args );

I didn’t see any reference to $theCatId, so I assume you’re handling that somewhere else in your script. Things could also be written more efficiently than what I did from your example code, but either way, this should hopefully help point you in the right direction of getting your desired result.

All of the above together:

    // Globals.
    global $wp_query, $paged, $post;

    // Shortcode attributes.
    $sc = shortcode_atts(
        array(
            'pagination' => 'true',
            'query' => '',
            'category' => '',
            'tag_name' => '',
            'custom_field_1' => '',
            'custom_field_2' => '',
            'relation_operator' => '',
            'number_posts' => '',
            'order_by'   => '',
            'order'     => '',
        ),
        $atts
    );

    // WP_Query arguments
    $args = array(
        'paged'          => ( int ) get_query_var( 'paged', 1 ),
        'post_type'      => array( 'page', ' post' ),
        'post_status'    => array( 'publish' ),
        'category_name'  => $sc['category'],
        'tag'            => $sc['tag_name'],
        'category__in'   => $theCatId,       
        'posts_per_page' => $sc['number_posts'],
        'order'          => $sc['order'],
        'orderby'        => $sc['order_by'],
    );

    // custom_field_1 is populated.
    if ( $sc['custom_field_1'] ) {

        // custom_field_2 is populated.
        if ( $sc['custom_field_2'] ) {
            $args['meta_query'] = array(
                    'relation' => $sc['relation_operator'],
                    array(
                        'key'     => $sc['custom_field_1'],
                        'value'   => '',
                        'compare' => '!=',
                    ),
                    array(
                        'key'     => $sc['custom_field_2'],
                        'value'   => '',
                        'compare' => '!=',
                    ),
                )
            );

        // custom_field_2 is not populated.
        } else {
            $args['meta_query'] = array(
                array(
                    'key'     => $sc['custom_field_1'],
                    'value'   => '',
                    'compare' => '!=',
                ),
            );
        }
    }

    // Custom query $my_query.
    $my_query = new WP_Query( $args );