With simple realization that we only find new matching words when we expand and we lose matching words when we shrink, we only need to compare words at either ends of the sliding window.
import collections
def find_word_concatenation(str1, words):
result_indices = []
n, k = len(words), len(words[0])
matched, counter = 0, collections.Counter(words)
start = 0
for end in range(len(str1)):
if end >= k-1:
word = str1[end-k+1:end+1]
if word in counter:
counter[word] -= 1
matched += not counter[word]
if end >= n*k-1:
if matched == n:
result_indices.append(start)
word = str1[start:start+k]
if word in counter:
counter[word] += 1
matched -= counter[word] > 0
start += 1
return result_indices