Generic makefile for C++ projects
It's reasonable to require GNU Make - it's available on all platforms that have their own Make (as far as I know), and trying to cope with the vagaries of all vendors' Make implementations is an exercise in futility.  So I think you've taken the right approach here.

You're working against Make by putting build products into subdirectories.  It's easier to build them into the working directory, and the sources can be found using VPATH, then there's no need to copy all the built-in rules (not so bad when all your source files are C++, but when you need to add a few assembler and C files, then the maintenance starts to grow).
Creating separate debug and release binaries in the same build tree is problematic - it can mean a total rebuild when switching from one kind to another.  It's more usual to have separate build directories for the two, so you can incrementally build either at any time (of course, they can share the same source files, using VPATH, and can share most of the Makefile the same way).
That would look something like this:
debug/Makefile
CXXFLAGS += -g3 -DDEBUG
VPATH = ../src:../include
include ../Makefile

release/Makefile
CXXFLAGS += -O2
VPATH = ../src:../include
include ../Makefile

Then, building the release version doesn't affect the objects used to build the debug version, and vice versa.

This target is problematic for a parallel build:

release: distclean $(PROGRAM)


We'll lose some of the files as the distclean isn't sequenced with respect to $(PROGRAM).
I don't like the explicit strip invocation in the release target: since install depends on release, this makes it impossible to build debug-symbol Debian packages the usual way.  Just let the packager do the stripping.

I see no value in redefining COMPILE.cc and LINK.cc: CXXFLAGS and LDFLAGS are provided specifically for you to add your own flags to these lines - just use them.
Speaking of which, we normally use += to add to the flags:
CPPFLAGS += -I$(INCDIR)
CXXFLAGS += -std=c++17 -Wall -Wextra -Wpedantic
CXXFLAGS += -flto

LDFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,-gc-sections

DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
CPPFLAGS += $(DEPFLAGS)


$(RM) is provided as a more portable alternative to rm -f; we could use that in a few places.
.DELETE_ON_ERROR is often missed - kudos for remembering that.
DESTDIR?= is a no-op - undefined Make variables already expand to nothing.  Just omit this line.  It's good that you're correctly allowing this to be set by packaging systems etc.