Double linked list code doesn't work:
void InsertAt(const T& data, unsigned int index){
      if(index >= node_count){
        throw out_of_range("Provided index exceeds linked list length!");
      }
      else if(index == 0){
        AddHead(data);
        node_count += 1;
      }
      else if(index == node_count){
        AddTail(data);
        node_count += 1;
      }
      else{
        Node* node_ptr = GetNode(index);
        Node* new_node_ptr = new Node(data);
        new_node_ptr->prev = node_ptr->prev;
        new_node_ptr->next = node_ptr;

        node_ptr->prev->next = new_node_ptr;
        node_ptr->prev = new_node_ptr;

        node_count += 1;
      }
    }

Valgrind error:
==5285== Memcheck, a memory error detector
==5285== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5285== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5285== Command: ./part3/main
==5285== 
=====Testing InsertAt() functionality=====
Initial list: 
great
benefit
linked
is
the
ability
to
easily
into
the
Node count: 10

Inserting words into the list with InsertAt()...
==5285== Invalid read of size 8
==5285==    at 0x10A5F4: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:266)
==5285==    by 0x109B13: TestInsertAt() (main.cpp:77)
==5285==    by 0x10942F: main (main.cpp:18)
==5285==  Address 0x28 is not stack'd, malloc'd or (recently) free'd
==5285== 
==5285== 
==5285== Process terminating with default action of signal 11 (SIGSEGV)
==5285==  Access not within mapped region at address 0x28
==5285==    at 0x10A5F4: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:266)
==5285==    by 0x109B13: TestInsertAt() (main.cpp:77)
==5285==    by 0x10942F: main (main.cpp:18)
==5285==  If you believe this happened as a result of a stack
==5285==  overflow in your program's main thread (unlikely but
==5285==  possible), you can try to increase the size of the
==5285==  main thread stack using the --main-stacksize= flag.
==5285==  The main thread stack size used in this run was 8388608.
==5285== 
==5285== HEAP SUMMARY:
==5285==     in use at exit: 878 bytes in 18 blocks
==5285==   total heap usage: 21 allocs, 3 frees, 81,774 bytes allocated
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 1 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A85E: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::AddHead(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (LinkedList.h:181)
==5285==    by 0x10A550: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:256)
==5285==    by 0x10990B: TestInsertAt() (main.cpp:72)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 2 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A5D1: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:265)
==5285==    by 0x109973: TestInsertAt() (main.cpp:73)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 3 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A5D1: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:265)
==5285==    by 0x1099DB: TestInsertAt() (main.cpp:74)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 4 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A5D1: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:265)
==5285==    by 0x109A43: TestInsertAt() (main.cpp:75)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 5 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A5D1: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:265)
==5285==    by 0x109AAB: TestInsertAt() (main.cpp:76)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 48 bytes in 1 blocks are still reachable in loss record 6 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A5D1: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::InsertAt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) (LinkedList.h:265)
==5285==    by 0x109B13: TestInsertAt() (main.cpp:77)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 55 bytes in 1 blocks are still reachable in loss record 7 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x4F632AC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==5285==    by 0x109784: TestInsertAt() (main.cpp:60)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 55 bytes in 1 blocks are still reachable in loss record 8 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x4F632AC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==5285==    by 0x4F58892: std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==5285==    by 0x1097BD: TestInsertAt() (main.cpp:61)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== 480 bytes in 10 blocks are still reachable in loss record 9 of 9
==5285==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5285==    by 0x10A38E: LinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::AddTail(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (LinkedList.h:195)
==5285==    by 0x10981C: TestInsertAt() (main.cpp:64)
==5285==    by 0x10942F: main (main.cpp:18)
==5285== 
==5285== LEAK SUMMARY:
==5285==    definitely lost: 0 bytes in 0 blocks
==5285==    indirectly lost: 0 bytes in 0 blocks
==5285==      possibly lost: 0 bytes in 0 blocks
==5285==    still reachable: 878 bytes in 18 blocks
==5285==         suppressed: 0 bytes in 0 blocks
==5285== 
==5285== For counts of detected and suppressed errors, rerun with: -v
==5285== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
bash: line 1:  5284 Done                    echo "$arg"
      5285 Segmentation fault      (core dumped) | valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 --undef-value-errors=no ./part3/main > "$output" 2>&1