I didn't do a deep dive, but something jumped out at me early. If this doesn't fix it, leave a comment and I'll look again.
Given that you're getting mostly correct results, its reasonable to assume that most of the code is working. So I'm immediately suspicious of the hash function. Now, look at this section of it:
int wordlength = strlen(word);
The bug is in your unload function. You return after cleaning up just 1 list. But you have 26 of them to get through. The outer loop is also out of bounds. You iterate up to N + 1 for some reason.
// Unloads dictionary from memory, returning true if successful, else false
for (int i = 0; i < (N + 1); i++) // Out of bounds. Should ...
I'm sorry, but this code is not passing valgrind.
~/go/test/pset5/ $ valgrind ./speller small
==223== Memcheck, a memory error detector
==223== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==223== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==223== Command: ./speller small
Actually, your load() function is absolutely fine. The problem is your hash() unction. Your not normalising (%) the hash value by table length. which is why node->next = table[index]results in seg fault, because index > table length
When using fscanf do we need to iterate through what it is writing to the buffer to check for the null signifier so we can jump in and strcpy that buffer into our new node?
No. fscanf will just stop when it hits the null terminator. It also copies the null terminator.
Does strcpy automatically detect the NULL signifier and stop copying at that point?