Your source of confusion is that you've misunderstood the meaning of the let construct. It does not modify an object: it's not an assignment statement (. The let construct gives a name to a value. The syntax of the let construct is
let name = value in expression
This causes name to refer to value in expression. The value is computed once, before binding the name to it. The scope of name is expression, so you can't use it to refer to value outside expression (the value, on the other hand, lives on until garbage collected).
The top-level let construct is similar to the one in expressions, but does not have the in expression part. The scope of the name is the rest of the program (it's as though there was an in part containing everything below, at least until you get to modules).
You're trying to modify the top-level m, but that is not let's job: you would need an assignment for that. Ocaml has an assignment operator, :=, which assigns to an existing reference. A reference is an object that can be modified. This is not automatic in Ocaml: unlike languages such as C, Java and Lisp, Ocaml does not use a single language feature to give names to values and to create modifiable storage. The ref function creates a modifiable object; you assign it with := and use the ! operator to get its value:
let r_m = ref StringMap.empty;; (*the type of r_m is 'a StringMap.t ref*)
let rec count ke = match ke with
| [] -> []
| hd::tl -> r_m := StringMap.add hd 1 !r_m; [hd] @ count tl;;
This is however not very good Ocaml style. Ocaml supports this imperative style, but you should avoid it because imperative programming is more error-prone than functional programming. The functional style is to create a new value whenever you want to modify an object. Note that maps created by the Map module are designed to support this style: add returns a new object which coexists with the old object (i.e. it's a persistent data structure). Switching to a functional style requires that you change the interface of the count function; it's something that you'd want to do anyway, to be able to use the count function on different maps by passing the map as an argument. I refer you to Sami's answer for example code in good Ocaml style.