This:
entry = list_search(key, list);
becomes: entry = list_search(key, lists[hash(key) % (sizeof(lists)/sizeof(lists[0]))]);
This: list_add(key, entry, list);
becomes: list_add(key, entry, lists[hash(key) % (sizeof(lists)/sizeof(lists[0]))]);
etc.A simple hash(), not high quality but good enough for non-adversarial inputs, can be a one-liner.
A good dictionary does more than this of course, especially dynamic sizing, but this simple change can radically speed up simple linked list code when the lists are long, you don't have a hash table implemention you can use, and you want to keep the code change very small.
The same principle can be used with other things than lists too.