It's actually pretty rare to overflow the stack. You have to have a recursive function that runs away. (I haven't looked too closely at your code to exclude this possibility.)
More common is memory fragmentation in the heap. Using the String objects in a particularly stupid way will cause the heap to grow over time and collide with the stack. You don't appear to be using String either.
Either of these cases will be uncovered by a freeRam() function. Make it print the free ram once per minute or something and watch it for a few minutes.
Here's a representative line from the pastebin code...
if (clockChecks[2] - clockChecks[1] > heaterDelay) { //check to see if heater has been off for at least 2 min.
OK, so you made an array called clockChecks[] because you know it's bad to have numbers in variable names. But you only ever use constants in the array! How the heck do you remember that clockChecks[1] is the heater time? You could do either clockChecks[Heater_Time] or just heaterTime. This has got to be very confusing to debug just a few days after it's been written. The fact that you had to write such a long comment for a simple expression means that it's already an issue.
The loop() function is also a little on the big side. Try to move all of that button-switch stuff into separate functions. Preferably into separate files. That will make it easier to debug.
while (client.connected()) {
Are you sure it's not getting stuck here?