Try this
<?php
//List of tag slugs
$tags = array();
$posttags = get_the_tags();
if ($posttags) {
foreach($posttags as $tag) {
$tags[] = $tag->term_id;
}
}
$args = array(
'tag__in' => $tags
//Add other arguments here
);
// This query contains posts with at least one matching tag
$tagged_posts = new WP_Query($args);
echo '<ul>';
while ( $tagged_posts->have_posts() ) : $tagged_posts->the_post();
// Check each single post for up to 3 matching tags and output <li>
$tag_count = 0;
$tag_min_match = 2;
foreach ( $tags as $tag ) {
if ( has_tag( $tag ) && $tag_count < $tag_min_match ) {
$tag_count ++;
}
}
if ($tag_count >= $tag_min_match) {
//Echo list style here
echo '<li><a href="'. get_permalink() .'" title="'. get_the_title() .'">'. get_the_title() .'</a></li>';
}
endwhile;
wp_reset_query();
echo '</ul>';
The code will fetch all the tags associated with the current post, search other posts with similar tags and return post if 2 or more tags are matched.
Hope this helps.