Product Filtering with Tags
Not sure i understand well, but to be sure: you want to be able to filter for (let's say you sell shirts) a Red AND Large shirt, so it filters only the shirts which contain the color red and that are available in large?

On that note, have you tried setting relatedToParam to and instead of or?

The answer you linked seems to work for multiple selections that are not related. For example: i want the website to show me all the red shirts and all the large shirts, but not necessarily just the red large shirts.

Following that logic, changing relatedToParam to and should do the trick?



EDIT (2019-02-07):

So, i tried quite a few solutions and that seems to be working, please read the comments.

EDIT 2:

There was an issue! 
For example, if no size was selected, the loop simply won't do nothing. You could switch the loop to start with types, but then again, if no type is selected, same problem. 
Now it's working but still really NOT versatile. 
Feel free to edit or comment with a better solution!

{% set sizes = craft.tags.group('size').all() %}
{% set types = craft.tags.group('type').all() %}

{# You'll need to separate tags inside the query itself #}
{# ?size=......&amp;type=...... #}

{# The split filter doesn't work directly on getParam #}

{# Error when getParam is empty #}
{# Because it is set to [] and we can't split on an array #}
{# You will need to find a little condition to make it bulletproof #}

{% set selectedSizesIds = craft.app.request.getParam('size') ?? [] %}
{% set selectedSizesIds = selectedSizesIds|split(',') %}

{% set selectedTypesIds = craft.app.request.getParam('type') ?? [] %}
{% set selectedTypesIds = selectedTypesIds|split(',') %}

{# You can actually use a if inside a print statement #}
{# Take a look at the "checked" print condition #}

{% for size in sizes %}
    &lt;input type="checkbox" name="tags[]" value="{{ size.id }}" {{ (size.id in selectedSizesIds) ? 'checked' : '' }}&gt;{{ size.title }}&lt;/input&gt;
{% endfor %}

{% for type in types %}
    &lt;input type="checkbox" name="tags[]" value="{{ type.id }}" {{ (type.id in selectedTypesIds) ? 'checked' : '' }}&gt;{{ type.title }}&lt;/input&gt;
{% endfor %}

{# Where it gets tricky #}
{% set relatedToParam = ['and'] %}

{# Loop through the second set of tags while looping through the first set of tags #}
{# Still not quite sure that's the best way to go but it works well #}

{% if selectedSizesIds|length &gt; 0 %}
    {% for size in selectedSizesIds %}
        {% if selectedTypesIds|length &gt; 0 %}
            {% for type in selectedTypesIds %}
                {% set relatedToParam = relatedToParam|merge([
                    { targetElement : [size,type] }
                ]) %}
            {% endfor %}
        {% else %}
            {% set relatedToParam = relatedToParam|merge([
                { targetElement : size }
            ]) %}
        {% endif %}
    {% endfor %}
{% elseif selectedTypesIds|length &gt; 0 %}
    {% for type in selectedTypesIds %}
        {% set relatedToParam = relatedToParam|merge([
            { targetElement : type }
        ]) %}
    {% endfor %}
{% endif %}

{% set relatedToParam = relatedToParam|length &gt; 1 ? relatedToParam : null %}

{% set entries = craft.products.type('accommodation').relatedTo(
    relatedToParam
).all() %}

{% for product in entries %}
   {{ product.title }}
{% endfor %}