You can use DP or DFS on bitmasks about the selection of words.
Here's a sample solution:
My solution:
// Sample solution by real_henry
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int n, k, res;
string s;
vector<int> l[25];
bool visited[50000000];
void dfs(int words, int letters, int num_words) { // words and letters are bitmasks
if (visited[words]) return;
if (num_words > n) return;
visited[words] = 1;
for (int i = 0; i < n; i++) {
if (words & (1 << i)) continue; // it contains this word, so skip
int new_letters = letters;
for (int letter : l[i]) new_letters |= (1 << letter);
if (__builtin_popcount(new_letters) > k) continue;
dfs(words | (1 << i), new_letters, num_words + 1);
}
res = max(res, num_words);
}
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> s;
l[i].resize(s.length());
for (int j = 0; j < s.length(); j++) l[i][j] = s[j] - 'a';
}
dfs(0, 0, 0);
cout << res << endl;
}