A dynamic programming language is a language which allows the definition of a program to be updated while the program is running. Tcl is a dynamic language.
In a(n idealized) static language, the control flow of operations to be performed, the layout of data objects (which does not necessarily mean objects in the object oriented sense of the word) to be used, and the type system to tie them together are all present and fixed at compilation. The source code is compiled to the exact machine codes needed to run the program, to be executed by the computer's processor. In a(n idealized) dynamic language, these components (control flow, objects, type system) can be altered and extended during execution of the program, and the language generally has a rich set of tools to do such manipulation. The source code is loaded and (it, or a representation of it) is later modified in-memory while the program is executed by an interpreter.
In modern practice, most static languages provide at least some dynamic features, and dynamic languages incorporate partial compilation (fully compiling a program written in a dynamic language is quite possible, but would just introduce unnecessary inefficiency and inflexibility).
Going back a few decades dynamic language programs would typically be interpreted from a text representation (which in most cases caused a performance hit); today it is more common to compile to bytecode to be executed by a virtual machine.
Some definitions of the concept of scripting language are strongly connected to dynamic programming, but the concepts are not synonymous. Tcl is a scripting language as well (by at least some definitions), so there's nothing wrong with using either term for Tcl.
Somewhat confusingly, the concept of dynamic programming (Wikipedia article ) is fairly unrelated to this dichotomy.