By "save a tileset" I think you mean saving tiles placed in map cells. That is pretty general question and method of doing this may vary depending on project and needs.
If you have small map with known const size you can just save info for all cells. Assuming you have map of size 100x100 you can do something like:
#Dictionary with tilemap data to save, you can save it as json or something
var myTileMapData : Dictionary = { "data": [] }
for y in 100:
for x in 100:
for layer in tilemap.get_layers_count():
if(myTileMapData.data.size() <= layer):
myTileMapData.data.append( [] )
var pos : Vector2i = Vector2i(x, y)
var coords : Vector2i = tilemap.get_cell_atlas_coords(layer, pos)
var source : int = tilemap.get_cell_source_id(layer, pos)
var altTile : int = tilemap.get_cell_alternative_tile(layer, pos)
myTileMapData.data[layer].append( { "pos": pos, "coords": coords, "source": source, "alt_tile": altTile } )
#Now you can save myTileMapData
var saveFile = FileAccess.open(savePath, FileAccess.WRITE)
if(FileAccess.get_open_error() != OK):
return false
saveFile.store_string(JSON.stringify(myTileMapData))
That is some simple example I did right now, not tested or anything.
If you have big procedural generated map then probably it would be much more efficient to store only some data about map required to rebuild it after loading (like seed from which map was generated and saving only cells modified by players) and split world into chunks as it is done in most cases (to allow easier streaming to/from hard drive).
Anyway I hope it gives you some ideas.