Custom Contains() function
Here is my first review. See what you can make of it! I left comments for you. They always discuss the code right below.

It is bad style to leave documentation tags empty. Either have no param tag or fill all with appropriate descriptions:

/// &lt;param name="content"&gt;&lt;/param&gt;
/// &lt;param name="SearchString"&gt;Search string&lt;/param&gt;
/// &lt;param name="NumberOfMatches"&gt;Specify how many words have to match in the search string.


Too much implementation detail in my opinion:

/// This value is automatically dropped when the user searches less words.
/// I.e. NumberOfMatches = 3 and the user searches 'Bob', NumberOfMatches gets set to 1.&lt;/param&gt;


Self explanatory name:

/// &lt;param name="MatchAllWords"&gt;If set to true, all of the words in the search string must be contained in what's being checked&lt;/param&gt;


This is self explanatory, remove the line:

/// &lt;returns&gt;&lt;/returns&gt;


Use a more telling name like ContainsWords:

public static bool ContainsV2(this string content, string SearchString, int NumberOfMatches = 1, bool MatchAllWords = false)
{
    var matches = 0;
    var numberOfWords = SearchString.Split(' ').Length;


Don't use empty comments like "Sets a variable" or "Updates value". Explain it better or leave out the comment:

    // Update required number of matches


The ?: operator is hard to understand and not necessary here. Rather, use something like in my comment:

    // if (NumberOfMatches &gt; numberOfWords)
    // {
    //    NumberOfMatches = numberOfWords;
    // }
    NumberOfMatches = NumberOfMatches &gt; numberOfWords ? 
                    numberOfWords : 
                    NumberOfMatches;


You already split the search string above. Either don't check for null or do it in the beginning:

    if (!string.IsNullOrEmpty(content) &amp;&amp; !string.IsNullOrEmpty(SearchString))
    {


This is confusing. Reduce the complexity and nesting depth:

        SearchString.Split(' ')
            .ToList()
            .ForEach(w =&gt; //Gets the index of each word after being split
                matches += content
                    .IndexOf(
                        StripNonAlphaNumeric(w), 
                        StringComparison.OrdinalIgnoreCase
                    ) &gt;= 0 ? 1 : 0
            );
    }


Rather set this at the start of the function. It is confusing here:

    if (MatchAllWords)
    {
        return matches == numberOfWords;
    }
    return matches &gt;= NumberOfMatches;
}