Multiple Category Search with and operator in WordPress

You are headed down the right path, but your syntax I think is a tiny bit off.

cat is in fact a public queryable variable. https://codex.wordpress.org/WordPress_Query_Vars#List_of_Query_Vars

Rather than the +, you’ll need to use a , instead and you’ll need a & in there to split them up. You should see results on your search page with something like:

Slug domain/?s=&cat=1999,2148

Assuming you are using post as the post_type and a category taxonomy.
Hope that helps!

Edit:

Here is a form that tries to include your fields like you have shown above:

<form role="search" method="get" id="searchform" action="">
    <select class="js-cat-one-field" required>
        <option value="">State</option>
        <option value="1293">North Carolina</option>
        <option value="1999">Virginia</option>
    </select>

    <select class="js-cat-two-field" required>
        <option value="">Qualificationn</option>
        <option value="1092">HTML</option>
        <option value="8321">CSS</option>
        <option value="2148">WordPress</option>
    </select>

  <input type="hidden" value="" name="s" />
  <input type="hidden" value="" name="cat" class="js-combined-cat" />
  <input type="submit" id="searchsubmit" value="Search" />
</form>

<script>
    var cat_one = document.querySelector('.js-cat-one-field'),
        cat_two = document.querySelector('.js-cat-two-field'),
        hidden_cat_field = document.querySelector('.js-combined-cat'),
        hidden_cat_value = [];

    cat_one.addEventListener("change", function() {
        updateHiddenField(this.value, 0);
    });

    cat_two.addEventListener("change", function() {
        updateHiddenField(this.value, 1);
    });

    function updateHiddenField(cat_value, index){
        hidden_cat_value[index] = cat_value;
        hidden_cat_field.value = hidden_cat_value;
    }
</script>

Few things to note:

  1. You are not searching anything other than your filters, you can use type="hidden" on the actual search field.
  2. You have two filters, with each needing their own unique name attributes. Because we want both values of them to be passed as one query string, we need to do some work behind the scenes to make that happen on form submission.
  3. This is a rough idea to help get you where you need to be. But I did test things on my end and it’s giving me what we are expecting to see.
  4. I used Vanilla JS just to show some basic concepts.